<?php


namespace App\Service\Cooperative;


use App\Constants\Model\TaskArbitration;
use App\Constants\Model\TaskExec;
use App\Dao\TaskArbitrationDao;
use App\Dao\TaskExecDao;
use App\Service\Common\TaskLogic;
use App\Utils\Log;
use App\Utils\Notice\EmployerArbitrateEnd;
use App\Utils\Notice\Sender;
use App\Utils\Notice\UserArbitrateEnd;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;

class TaskExecService extends BaseService
{

    /**
     * @Inject()
     * @var TaskExecDao
     */
    protected $taskExecDao;

    /**
     * @Inject()
     * @var TaskArbitrationDao
     */
    protected $taskArbitrationDao;

    /**
     * @Inject()
     * @var TaskLogic
     */
    protected $taskLogic;

    /**
     * @param array $where
     * @return array
     */
    public function index(array $where): array
    {
        $where['cooperative_id'] = $this->user()->cooperative_id;
        $where['status'] = $where['status'] > 0 ? $where['status'] : 0;
        $pageInfo = $this->extractPaginateInfo($where);
        $index = $this->taskArbitrationDao->where($where)->with(['user', 'task'])->paginate(
            $pageInfo['perPage'], ['*'], 'page', $pageInfo['page']
        );
        return $this->formatIndex($index);
    }

    public function formatIndex(\Hyperf\Contract\LengthAwarePaginatorInterface $index)
    {
        $data = [];
        /** @var \App\Model\TaskArbitration $taskArbitration */
        foreach ($index->items() as $taskArbitration) {
            $data[] = [
                'id' => $taskArbitration->task_exec_id,
                'arbitration_id'=> $taskArbitration->id,
                'task_id' => $taskArbitration->task_id,
                'user_avatar' => $taskArbitration->user->avatar,
                'user_name' => $taskArbitration->user->nickname,
                'user_phone' => $taskArbitration->user->phone,
                'task_price' => $taskArbitration->task->price,
                'task_title' => $taskArbitration->task->title,
                'created_time' => $taskArbitration->created_at->toDateTimeString(),
                'status' => $taskArbitration->status,
            ];
        }
        return [
            'data' => $data,
            'current_page' => $index->currentPage(),
            'total' => $index->total(),
            'per_page' => $index->perPage()
        ];
    }

    /**
     * 仲裁-悬赏主胜
     * @param int $taskExecId
     * @param array $data
     * @throws \Exception
     */
    public function employerWin(int $taskExecId, array $data)
    {
        /** @var \App\Model\TaskExec $taskExec */
        $taskExec = $this->taskExecDao->firstOrFail([
            'id' => $taskExecId,
            'cooperative_id' => $this->user()->cooperative_id,
            'arbitration_status' => TaskExec::ARBITRATION_STATUS_NOT
        ]);
        $taskExec->arbitration_status = TaskExec::ARBITRATION_STATUS_HAS;

        $taskArbitration = $taskExec->taskArbitration;
        $taskArbitration->status = TaskArbitration::STATUS_EMPLOYER_WIN;
        $taskArbitration->context = $data['context'];

        Db::beginTransaction();
        try {
            $taskExec->save();
            $taskArbitration->save();

            //归还悬赏主任务数量或退款
            $this->taskLogic->taskReturn([
                'employer_id' => $taskExec->employer_id,
                'task_id' => $taskExec->task_id
            ]);

            //发送用户通知
            Sender::send($taskExec->user_id, new UserArbitrateEnd());
            //发送悬赏主通知
            Sender::send($taskExec->employer_id, new EmployerArbitrateEnd());

            Db::commit();
        } catch (\Exception $exception) {
            Db::rollBack();
            Log::get()->error($exception->getMessage(), ['task_exec_id' => $taskExecId]);
            throw $exception;
        }

    }

    /**
     * 仲裁-用户胜
     * @param int $taskExecId
     * @param array $data
     * @throws \Exception
     */
    public function userWin(int $taskExecId, array $data)
    {
        /** @var \App\Model\TaskExec $taskExec */
        $taskExec = $this->taskExecDao->firstOrFail([
            'id' => $taskExecId,
            'cooperative_id' => $this->user()->cooperative_id,
            'arbitration_status' => TaskExec::ARBITRATION_STATUS_NOT
        ]);
        $taskExec->arbitration_status = TaskExec::ARBITRATION_STATUS_HAS;

        $taskArbitration = $taskExec->taskArbitration;
        $taskArbitration->status = TaskArbitration::STATUS_USER_WIN;
        $taskArbitration->context = $data['context'];

        Db::beginTransaction();
        try {
            $taskExec->save();
            $taskArbitration->save();

            //给用户结算佣金
            $this->taskLogic->commissionIncome([
                'user_id' => $taskExec->user_id,
                'task_id' => $taskExec->task_id
            ]);

            //发送用户通知
            Sender::send($taskExec->user_id, new UserArbitrateEnd());
            //发送悬赏主通知
            Sender::send($taskExec->employer_id, new EmployerArbitrateEnd());

            Db::commit();
        } catch (\Exception $exception) {
            Db::rollBack();
            Log::get()->error($exception->getMessage(), ['task_exec_id' => $taskExecId]);
            throw $exception;
        }

    }

    public function urgeIndex(array $where)
    {
        $pageInfo = $this->extractPaginateInfo($where);
        $where['cooperative_id'] = $this->user()->cooperative_id;
        $where['audit_status'] = TaskExec::AUDIT_STATUS_NOT;
        $index = $this->taskExecDao
            ->where($where)
            ->whereRaw("audit_time_end >" . time() - TaskExec::NOT_AUDIT_NOTICE_TIME)
            ->with(['user', 'employer.user', 'task'])
            ->paginate(
                $pageInfo['perPage'], ['*'], 'page', $pageInfo['page']
            );
        return $this->formatUrgeIndex($index);
    }

    public function formatUrgeIndex(\Hyperf\Contract\LengthAwarePaginatorInterface $index)
    {
        $data = [];
        /** @var \App\Model\TaskExec $taskExec */
        foreach ($index->items() as $taskExec) {
            $data[] = [
                'id' => $taskExec->id,
                'user_name' => $taskExec->user->nickname,
                'employer_name' => $taskExec->employer->user->nickname,
                'employer_phone' => $taskExec->employer->user->phone,
                'audit_time_end' => date('Y-m-d H:i:s',$taskExec->audit_time_end),
                'task' => [
                    'task_id' => $taskExec->task->id,
                    'task_title' => $taskExec->task->title,
                    'task_price' => $taskExec->task->price,
                    'task_cover_image' => $taskExec->task->cover_image,
                    'task_tags' => $taskExec->task->tags,
                ]
            ];
        }
        return [
            'data' => $data,
            'current_page' => $index->currentPage(),
            'total' => $index->total(),
            'per_page' => $index->perPage()
        ];
    }
}